#encoding: utf-8

import cotyledon
from stevedore import enabled
from oslo_log import log
from oslo_config import cfg
import time
import random

service_opts = []

#PROCESSORS_NAMESPACE = 'mytest.processors'
#PROCESSORS_NAMESPACE = 'cloudkitty.rating.processors'
PROCESSORS_NAMESPACE = 'studycloudkitty.processors'

cfg.CONF.register_opts(service_opts)

LOG = log.getLogger(__name__)

class EnabledExtensionManager(enabled.EnabledExtensionManager):
    """CloudKitty Rating processor manager

    Override default EnabledExtensionManager to check for an internal
    object property in the extension.
    """

    def __init__(self, namespace, invoke_args=(), invoke_kwds={}):

        def check_enabled(ext):
            """Check if extension is enabled.

            """
            return ext.obj.enabled

        super(EnabledExtensionManager, self).__init__(
            namespace=namespace,
            check_func=check_enabled,
            invoke_on_load=True,
            invoke_args=invoke_args,
            invoke_kwds=invoke_kwds,
        )

class Worker(object):
    def __init__(self, _worker_id, tenant_id=None):
        self._tenant_id = tenant_id
        self._worker_id = _worker_id
        self._processors = []
        
        processors = EnabledExtensionManager(
            PROCESSORS_NAMESPACE,
            invoke_kwds={})

        for processor in processors:
            LOG.info('get processor %s'%(processor.name))
            self._processors.append(processor)
        self._processors.sort(key=lambda x: x.obj.priority, reverse=True)

    def run(self):
        while True:
          t = random.randint(1,7)
          if t == 7:
              LOG.info('I am %s, exiting Worker.run ...'%(self._worker_id))
              break 
          LOG.info("I am %s, working %s second%s"%(self._worker_id, t, 's' if t > 1 else ''))
          for processor in self._processors:
              LOG.info('I am %s , %s report quote: %s'%(self._worker_id, processor.name, processor.obj.quote()))
          time.sleep(t)
 
class Orchestrator(cotyledon.Service):
    def __init__(self, worker_id):
        self._worker_id = worker_id
        super(Orchestrator, self).__init__(self._worker_id)

    def run(self):
        while True: 
            """ 
            要加上while True，否则Worker进程如果跳出run()会停在 time.sleep(1)之后，但不会退出.
            """
            # 在Worker进程内创建新的Worker结构 
            worker = Worker(self._worker_id)
            LOG.info('Started worker {}. {}'.format(self._worker_id, worker))
            worker.run()
            LOG.info('I am %s, end after 1 second'%self._worker_id)
            time.sleep(1)

class OrchestratorServiceManager(cotyledon.ServiceManager):

    def __init__(self):
        super(OrchestratorServiceManager, self).__init__()
        self.service_id = self.add(Orchestrator,
                                   workers=3)

def main():
    log.register_options(cfg.CONF)
    log.set_defaults()
    log.setup(cfg.CONF, 'cloudkitty')

    OrchestratorServiceManager().run()


if __name__ == '__main__':
    main()

